package com.soft.trading;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo;

import java.util.List;

import static com.soft.trading.NodeFinder.findNodeByDescription;
import static com.soft.trading.NodeFinder.findNodeById;
import static com.soft.trading.NodeFinder.findNodeByText;
import static com.soft.trading.NodeFinder.getRootNode;
import static com.soft.trading.NodeFinder.performClick;

/**
 * 查找并操作UI元素的核心方法
 */
public class UIOperator {
    private static final String TAG = "UIOperator";

    /**
     * 通过多种策略查找并点击按钮
     */
    public boolean clickTargetButton() {
        AccessibilityNodeInfo rootNode = getRootNode();
        if (rootNode == null) {
            Log.e(TAG, "无法获取根节点");
            return false;
        }

        try {
            // 策略1: 通过资源ID查找（最可靠）
            AccessibilityNodeInfo buttonById = findNodeById(rootNode, "com.example.targetapp:id/login_button");
            if (buttonById != null && buttonById.isClickable()) {
                Log.d(TAG, "通过ID找到按钮，执行点击");
                return performClick(buttonById);
            }

            // 策略2: 通过文本内容查找
            AccessibilityNodeInfo buttonByText = findNodeByText(rootNode, "登录");
            if (buttonByText != null && buttonByText.isClickable()) {
                Log.d(TAG, "通过文本找到按钮，执行点击");
                return performClick(buttonByText);
            }

            // 策略3: 通过描述文本查找
            AccessibilityNodeInfo buttonByDesc = findNodeByDescription(rootNode, "登录按钮");
            if (buttonByDesc != null && buttonByDesc.isClickable()) {
                Log.d(TAG, "通过描述找到按钮，执行点击");
                return performClick(buttonByDesc);
            }

            // 策略4: 通过类名和索引查找
            List<AccessibilityNodeInfo> buttons = rootNode.findAccessibilityNodeInfosByViewId("android.widget.Button");
            for (AccessibilityNodeInfo button : buttons) {
                if (button.isClickable() && button.getText() != null &&
                        button.getText().toString().contains("登录")) {
                    Log.d(TAG, "通过类名和文本找到按钮，执行点击");
                    return performClick(button);
                }
            }

            Log.e(TAG, "未找到目标按钮");
            return false;

        } finally {
            rootNode.recycle();
        }
    }

    /**
     * 在输入框中输入文本
     */
    public boolean inputTextInField() {
        AccessibilityNodeInfo rootNode = getRootNode();
        if (rootNode == null) return false;

        try {
            // 查找输入框
            AccessibilityNodeInfo editText = findInputField(rootNode);
            if (editText == null) {
                Log.e(TAG, "未找到输入框");
                return false;
            }

            // 确保输入框可聚焦
            if (!editText.isFocusable()) {
                Log.d(TAG, "输入框不可聚焦，尝试点击激活");
                performClick(editText);

                // 等待输入框激活
//                new Handler(Looper.getMainLooper()).postDelayed(() -> {
//                    inputTextInField(); // 重试
//                }, 500);
                return true;
            }

            // 执行输入操作
            return inputText(editText, "13800138000");

        } finally {
            rootNode.recycle();
        }
    }

    /**
     * 查找输入框的多种策略
     */
    private AccessibilityNodeInfo findInputField(AccessibilityNodeInfo rootNode) {
        // 策略1: 通过资源ID查找
        AccessibilityNodeInfo field = findNodeById(rootNode, "com.example.targetapp:id/phone_input");
        if (field != null) return field;

        // 策略2: 通过类名和提示文本查找
        List<AccessibilityNodeInfo> editTexts = rootNode.findAccessibilityNodeInfosByViewId("android.widget.EditText");
        for (AccessibilityNodeInfo editText : editTexts) {
//            if (editText.getHintText().toString() != null &&
//                    editText.getHintText().toString().contains("手机号")) {
//                return editText;
//            }
        }

        // 策略3: 通过父容器结构查找
        return findInputFieldByLayout(rootNode);
    }

    /**
     * 通过布局结构查找输入框
     */
    private AccessibilityNodeInfo findInputFieldByLayout(AccessibilityNodeInfo rootNode) {
        // 查找包含"手机"文本的TextView，然后找相邻的EditText
        List<AccessibilityNodeInfo> textViews = rootNode.findAccessibilityNodeInfosByText("手机");
        for (AccessibilityNodeInfo textView : textViews) {
            AccessibilityNodeInfo parent = textView.getParent();
            if (parent != null) {
                // 在父节点中查找EditText
                for (int i = 0; i < parent.getChildCount(); i++) {
                    AccessibilityNodeInfo child = parent.getChild(i);
                    if (child != null && child.getClassName() != null &&
                            child.getClassName().toString().equals("android.widget.EditText")) {
                        return child;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 输入文本的核心方法
     */
    private boolean inputText(AccessibilityNodeInfo node, String text) {
        if (node == null || text == null) return false;

        try {
            // 方法1: 直接设置文本（API 21+）
            Bundle arguments = new Bundle();
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
            if (node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)) {
                Log.d(TAG, "直接设置文本成功: " + text);
                return true;
            }

            // 方法2: 模拟键盘输入（兼容性更好）
//            ClipboardManager clipboard = (ClipboardManager)
//                    getSystemService(Context.CLIPBOARD_SERVICE);
//            ClipData clip = ClipData.newPlainText("label", text);
//            clipboard.setPrimaryClip(clip);

            // 粘贴操作
            if (node.performAction(AccessibilityNodeInfo.ACTION_PASTE)) {
                Log.d(TAG, "粘贴文本成功: " + text);
                return true;
            }

            // 方法3: 逐个字符输入（最后手段）
            return inputTextCharByChar(node, text);

        } catch (Exception e) {
            Log.e(TAG, "输入文本失败", e);
            return false;
        }
    }

    /**
     * 逐个字符输入（兼容性最好）
     */
    private boolean inputTextCharByChar(AccessibilityNodeInfo node, String text) {
        // 先清除原有文本
        Bundle clearArgs = new Bundle();
        clearArgs.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "");
        node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, clearArgs);

        // 逐个字符输入
        for (char c : text.toCharArray()) {
            Bundle args = new Bundle();
            args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
                    String.valueOf(c));
            if (!node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args)) {
                Log.e(TAG, "输入字符失败: " + c);
                return false;
            }

            // 短暂延迟
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }

        Log.d(TAG, "逐个字符输入完成: " + text);
        return true;
    }

    /**
     * 点击提交按钮
     */
    public boolean clickSubmitButton() {
        AccessibilityNodeInfo rootNode = getRootNode();
        if (rootNode == null) return false;

        try {
            // 查找提交按钮
            String[] submitButtonIds = {
                    "com.example.targetapp:id/submit_btn",
                    "com.example.targetapp:id/confirm_button",
                    "com.example.targetapp:id/ok_button"
            };

            String[] submitButtonTexts = {"提交", "确认", "确定", "完成", "下一步"};

            for (String buttonId : submitButtonIds) {
                AccessibilityNodeInfo button = findNodeById(rootNode, buttonId);
                if (button != null && button.isClickable()) {
                    Log.d(TAG, "找到提交按钮，执行点击");
                    return performClick(button);
                }
            }

            for (String text : submitButtonTexts) {
                AccessibilityNodeInfo button = findNodeByText(rootNode, text);
                if (button != null && button.isClickable()) {
                    Log.d(TAG, "通过文本找到提交按钮: " + text);
                    return performClick(button);
                }
            }

            Log.e(TAG, "未找到提交按钮");
            return false;

        } finally {
            rootNode.recycle();
        }
    }
}
